cmake_minimum_required(VERSION 3.27)
project(design-mode)

add_compile_options("/source-charset:utf-8")

set(BUILD_TYPE "Debug" CACHE STRING "构建类型")

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_BUILD_TYPE ${BUILD_TYPE})

option(SIMPLE_FACTORY_PATTERN "简单工厂模式" ON)
option(STRATEGY "策略模式" ON)
option(DECORATOR "装饰模式" ON)
option(PROXY "代理模式" ON)
option(FACTORY_METHOD "工厂方法模式" ON)
option(PROTOTYPE "原型模式" ON)
option(TEMPLATE_METHOD "模板方法模式" ON)
option(FACADE "外观模式" ON)
option(BUILDER "建造者模式" ON)
option(OBSERVER "观察者/发布者-订阅者模式" ON)
option(ABSTRACT_FACTORY "抽象工厂模式" ON)
option(STATE "状态模式" ON)
option(ADAPTER "适配器模式" ON)
option(MEMENTO "备忘录模式" ON)
option(COMPOSITE "组合模式" ON)
option(ITERATOR "迭代器模式" ON)
option(SINGLETON "单例模式" ON)
option(BRIDGE "桥接模式" ON)
option(COMMAND "命令模式" ON)
option(CHAINOFRESPONSIBILITY "职责链模式" ON)
option(MEDIATOR "中介者模式" ON)

if(MSVC)
    # 启用目录结构
    set_property(GLOBAL PROPERTY USE_FOLDERS ON)
    file(GLOB_RECURSE MODULE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
    source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${MODULE_SRC})
endif()

include_directories(${CMAKE_CURRENT_SOURCE_DIR})

# 如果当前是DEBUG则生成可执行程序，RELEASE则生成库文件
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
    add_executable(
        ${PROJECT_NAME}
        ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
    )
else()
    add_library(${PROJECT_NAME} STATIC)
endif()

add_subdirectory(base)

if(SIMPLE_FACTORY_PATTERN)
    add_definitions(-DSIMPLE_FACTORY_PATTERN)
    add_subdirectory(SimpleFactoryPattern)
endif()
if(STRATEGY)
    add_definitions(-DSTRATEGY)
    add_subdirectory(Strategy)
endif()
if(DECORATOR)
    add_definitions(-DDECORATOR)
    add_subdirectory(Decorator)
endif()
if(PROXY)
    add_definitions(-DPROXY)
    add_subdirectory(Proxy)
endif()
if(FACTORY_METHOD)
    add_definitions(-DFACTORY_METHOD)
    add_subdirectory(FactoryMethod)
endif()
if(PROTOTYPE)
    add_definitions(-DPROTOTYPE)
    add_subdirectory(Prototype)
endif()
if(TEMPLATE_METHOD)
    add_definitions(-DTEMPLATE_METHOD)
    add_subdirectory(TemplateMethod)
endif()
if(FACADE)
    add_definitions(-DFACADE)
    add_subdirectory(Facade)
endif()
if(BUILDER)
    add_definitions(-DBUILDER)
    add_subdirectory(Builder)
endif()
if(OBSERVER)
    add_definitions(-DOBSERVER)
    add_subdirectory(Observer)
endif()
if(ABSTRACT_FACTORY)
    add_definitions(-DABSTRACT_FACTORY)
    add_subdirectory(AbstractFactory)
endif()
if(STATE)
    add_definitions(-DSTATE)
    add_subdirectory(State)
endif()
if(ADAPTER)
    add_definitions(-DADAPTER)
    add_subdirectory(Adapter)
endif()
if(MEMENTO)
    add_definitions(-DMEMENTO)
    add_subdirectory(Memento)
endif()
if(COMPOSITE)
    add_definitions(-DCOMPOSITE)
    add_subdirectory(Composite)
endif()
if(ITERATOR)
    add_definitions(-DITERATOR)
    add_subdirectory(Iterator)
endif()
if(SINGLETON)
    add_definitions(-DSINGLETON)
    add_subdirectory(Singleton)
endif()
if(BRIDGE)
    add_definitions(-DBRIDGE)
    add_subdirectory(Bridge)
endif()
if(COMMAND)
    add_definitions(-DCOMMAND)
    add_subdirectory(Command)
endif()
if(CHAINOFRESPONSIBILITY)
    add_definitions(-DCHAINOFRESPONSIBILITY)
    add_subdirectory(ChainOfResponsibility)
endif()
if(MEDIATOR)
    add_definitions(-DMEDIATOR)
    add_subdirectory(Mediator)
endif()